package github.ziwukun.jsonql.lang;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;

/**JsonQL中的值类型
 * @author Hugo.Yu
 */
public enum JsonValType{
	/**
	 * 普通JSON对象
	 */
	OBJECT {
		@Override
		boolean isType(String str) {
			return JSONUtil.isJsonObj(str);
		}
	},
	/**
	 * 普通JSON数组
	 */
	ARRAY{
		@Override
		boolean isType(String str) {
			return JSONUtil.isJsonArray(str);
		}
	},
	/**
	 * 时间类型字符串<br>
	 * 格式：HH:mm:ss.SSS | HH:mm:ss
	 */
	TIME{
		@Override
		boolean isType(String str) {
			return ReUtil.isMatch("^\\d{2}:\\d{2}:\\d{2}\\.\\d{1,3}", str) || 
				ReUtil.isMatch("^\\d{2}:\\d{2}:\\d{2}", str);
		}
	},
	/**
	 * 日期类型字符串<br>
	 * 格式：<br>
	 * yyyy-MM-dd<br>
	 * yyyy/MM/dd<br>
	 * yyyy-MM-dd HH:mm:ss<br>
	 * yyyy/MM/dd HH:mm:ss<br>
	 * yyyy-MM-dd HH:mm:ss.SSS<br>
	 * yyyy/MM/dd HH:mm:ss.SSS<br>
	 */
	DATE{
		@Override
		boolean isType(String str) {
			return
				//yyyy-MM-dd
				ReUtil.isMatch("^\\d{1,4}-\\d{2}-\\d{2}", str) || 
				//yyyy/MM/dd
				ReUtil.isMatch("^\\d{1,4}/\\d{2}/\\d{2}", str) || 
				//yyyy-MM-dd HH:mm:ss
				ReUtil.isMatch("^\\d{1,4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}", str) || 
				//yyyy/MM/dd HH:mm:ss
				ReUtil.isMatch("^\\d{1,4}/\\d{2}/\\d{2} \\d{2}:\\d{2}:\\d{2}", str) || 
				//yyyy-MM-dd HH:mm:ss.SSS
				ReUtil.isMatch("^\\d{1,4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{1,3}", str) || 
				//yyyy/MM/dd HH:mm:ss.SSS
				ReUtil.isMatch("^\\d{1,4}/\\d{2}/\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{1,3}", str);
		}
	},
	/**数值类型
	 */
	NUMBER{
		@Override
		boolean isType(String str) {
			return NumberUtil.isNumber(str);
		}
	},
	/**
	 * 字符串类型
	 */
	STR{
		@Override
		boolean isType(String str) {
			return StrUtil.isNotBlank(str) && !OBJECT.isType(str) && !ARRAY.isType(str);
		}
	},
	/**
	 * 默认类型
	 */
	DEFAULT{
		@Override
		boolean isType(String str) {
			return true;
		}
		
	};
	
	/**检查字符串是否符合类型的要求
	 */
	abstract boolean isType(String str);
	
	/**检查支付串是否支持指定的JSON值类型
	 */
	public static boolean support(String checkStr,JsonValType...types) {
		for (JsonValType type : types) {
			if(!type.isType(checkStr)) {
				return false;
			}
		}
		return true;
	}
}
